筆者自己為K8S算是蠻初階的使用者, 本身也並非軟體產業, 只是因為工作上需要大量資料處理而需要研究K8S, 這次因為朋友的呼喚~~而來參加這次活動, 不能算是專業, 但想要分享一下自己的學習心得
寫這篇想要分享的重點:
從實體機(Bare Metal)一路演進到容器編排(Container Orchestration)的歷史,並一探 Kubernetes Cluster(Control Plane 與 Worker Node)的全貌。這篇想要講什麼:
- 基礎架構演進史:裸機、虛擬機、容器與容器編排的誕生背景。
- K8s Cluster 的比喻:Control Plane 與 Worker Node 各自負責什麼?
- 容器運行時(Container Runtime)演進:Docker 走入歷史與 Containerd / CRI / OCI 的關係。
為何要寫這篇:
許多人在學習 Kubernetes 時,往往直接陷入繁複的kubectl指令與 YAML 欄位,卻忽略了「為什麼需要 K8s」。理解技術演進與架構全貌,才能在日後面對複雜故障時,迅速定位問題發生的層級。
Cluster: 叢集
Container: 容器
Scheduler: 調度
要理解 Kubernetes,要先看看基礎架構演進歷史:
+-----------------+ +-----------------+ +-----------------+ +-----------------+
| Bare Metal | --> | Virtual Machine| --> | Container | --> | Orchestration |
| (物理機/裸機時代) | | (虛擬化時代) | | (輕量容器時代) | | (K8s 編排時代) |
+-----------------+ +-----------------+ +-----------------+ +-----------------+
Bare Metal(裸機時代):
應用程式直接運行在實體伺服器上。
問題: 部署極慢、資源利用率低(單一 App 很難吃滿整台 Server)、環境依賴容易衝突,且備援與擴充成本高。
Virtual Machine(虛擬機時代):
透過 Hypervisor(如 ESXi, KVM)在實體機上劃分出多個帶有完整 Guest OS 的 VM。
問題: 解決了資源隔離,但 Guest OS 相當吃重,啟動動輒數分鐘,開銷(Overhead)依然龐大。
Container(容器時代):
共享 Host OS Kernel,透過 Linux 的 Namespace(隔離資源)與 cgroups(限制資源)實現輕量化的program隔離。
問題: 當容器數量從十幾個增加到數千個,手動管理容器的生命週期、跨節點網路與自動擴充變得十分困難。
Container Orchestration(容器交響樂團!):
Kubernetes 誕生! 扮演「自動調度總指揮」,將每個容器化身為樂手。系統總指揮負責跨節點的自動化部署、彈性擴充、自我修復(Self-healing)與負載平衡,讓整個應用程式如同交響樂般和諧順暢地運行。
要理解抽象概念最好的方法就是視覺化。雖然網路上已有不少優秀的比喻,但筆者認為用「智慧工廠」來對照最為直覺,以下為架構示意圖:
+-----------------------------------------------------------------------+
| MASTER NODE (Control Plane) |
| |
| +-------------------+ +-------------------+ +-------------------+ |
| | etcd Cluster | | kube-scheduler | | Controller Manager| |
| | (廠區資料庫/生產總帳) | | (產線排程/資源分配) | | (品管/自動補單員) | |
| +---------+---------+ +---------+---------+ +---------+---------+ |
| ^ ^ ^ |
| | | | |
| +----------------------+----------------------+ |
| | |
| +----------v----------+ |
| | kube-apiserver | |
| | (中控室/總指揮) | |
| +----------+----------+ |
+-----------------------------------|-----------------------------------+
| (內部指令網路 / REST API)
+-----------------------------+-----------------------------+
| |
v v
+-----------------------------+ +-----------------------------+
| WORKER NODE 1 (一號廠房) | | WORKER NODE 2 (二號廠房) |
| | | |
| +-----------------------+ | | +-----------------------+ |
| | Kubelet | | | | Kubelet | |
| | (廠房廠長) | | | | (廠房廠長) | |
| +-----------+-----------+ | | +-----------+-----------+ |
| | | | | |
| +-----------v-----------+ | | +-----------+-----------+ |
| | Container Runtime | | | | Container Runtime | |
| | (自動化製造機具/機台) | | | | (自動化製造機具/機台) | |
| +-----------+-----------+ | | +-----------+-----------+ |
| | (拉取藍圖/Image 實體化) | (拉取藍圖/Image 實體化)
| +-----------v-----------+ | | +-----------+-----------+ |
| | Pods / Containers | | | | Pods / Containers | |
| | (多功能機台/加工產品) | | | | (多功能機台/加工產品) | |
| +-----------------------+ | | +-----------------------+ |
| | | |
| +-----------------------+ | | +-----------------------+ |
| | kube-proxy | | | | kube-proxy | |
| | (廠區物流/輸送帶分流) | | | | (廠區物流/輸送帶分流) | |
| +-----------------------+ | | +-----------------------+ |
+-----------------------------+ +-----------------------------+
kubectl),還是向廠房下達生產指令,全部由中控室統一驗證與派發。Kubelet(廠房廠長): 駐紮在個別廠房(Node)的現場最高主管。負責接收中控室的派工單,指揮現場機具(Container Runtime)讀取設計圖(Image)並啟動運作,同時向中控室回報廠房設備健康度。
Container Runtime(自動化製造機具 / 3D印表機): 真正執行實體化作業的底層設備(如 Containerd)。它接收廠長指令,拉取規格藍圖(Image),並將其「製造/運行」成為活生生的作業單元(Container)。
Pods / Containers(多功能加工機台 / 運作中的產品):
💡 觀念提醒: 真正在處理資料、執行程式碼的是 Container,而 Pod 只是 K8s用來封裝與提供執行環境的載體。
背景: 在 Kubernetes 發展早期,Docker 是當時的容器標準。
問題: 但 Docker 本身是一個龐大的 monolithic 工具(太肥大),並不完全符合 K8s 輕量化介面的需求。
【早期笨重架構】Docker Era (Deprecated / v1.24 前)
----------------------------------------------------------------------------------------
[ Kubelet ]
│
▼ (非標準轉接層)
[ dockershim ] ──► (K8s 硬維護的翻譯官,負責把 CRI 轉成 Docker API)
│
▼ (Docker API)
[ Docker Daemon (dockerd) ] ──► 龐大 Monolith!包辦了 Build、Swarm、CLI、Network 等多餘功能
│
▼
[ containerd ]
│
▼ [ OCI Standard ]
[ runc ]
│
▼
( Container 容器 )
【現代輕量架構】Direct CRI Era (現代 K8s 標準)
----------------------------------------------------------------------------------------
[ Kubelet ]
│
▼ (CRI Protocol / gRPC)
[ CRI Standard ]
│
├─────────────────────────────┐
▼ ▼
[ containerd ] (或) [ CRI-O ] ──► 專為 K8s 打造的極簡 Runtime
│ │
└──────────────┬──────────────┘
│
▼ [ OCI Standard ]
[ runc ]
│
▼
( Container 容器 )
關鍵改進與解法
OCI (Open Container Initiative) 標準化: 制定了容器鏡像如何打包(image-spec)以及容器如何在底層被執行的規範(runtime-spec,例如最普遍的 runc)。
CRI (Container Runtime Interface) 解耦: 由 K8s 社群定義的通用 API 介面。將容器運行時與 K8s 核心架構解耦,只要實作 CRI 規範的容器引擎,皆可直接插拔接上 K8s。
Dockershim 的正式退場: 早期因 Docker 未實作 CRI,K8s 官方必須額外維護 dockershim 作為銜接橋樑。直到 v1.24 版本,dockershim 被徹底移除,由專一且輕量的 containerd(從 Docker 拆分並捐贈給 CNCF 的項目)與 CRI-O 成為現代 K8s 主流的 Runtime。
當需要在 Node 上手動排查容器問題時,工具的選擇至關重要:
ctr: Containerd 原生 CLI,功能低階且對使用者不友善,僅適合底層除錯。nerdctl: 介面與 docker CLI 幾乎一模一樣,適合習慣使用 Docker 命令的開發者。crictl: 由 K8s 社群維護、專為 CRI 設計的 CLI,能感知 Pod 的概念。⚠️ 重要提醒: 使用
crictl或nerdctl手動建立容器或 Pod 僅供測試與除錯!因為船長Kubelet對手動建立的容器毫無感知,不久後就會將其刪除。
kubectl run 時,API Server、etcd、Scheduler 與 Kubelet 之間到底經歷了怎樣的動作?敬請期待!